package top.goldenyear.porpoise.framework.web.core.generator.dialect.impl;

import top.goldenyear.porpoise.framework.web.core.generator.dialect.IDialect;
import top.goldenyear.porpoise.framework.web.core.generator.model.ColumnMeta;
import top.goldenyear.porpoise.framework.web.core.generator.model.TableMeta;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 默认方言抽象类
 *
 * @author airhead
 */
public abstract class BaseJdbcDialect implements IDialect {

  @Override
  public void buildTableColumns(TableMeta tableMeta, DatabaseMetaData dbMeta, Connection conn)
      throws SQLException {
    Map<String, String> columnRemarks = buildColumnRemarks(tableMeta, dbMeta, conn);
    String sql = forBuildColumnsSql(tableMeta.getSchema(), tableMeta.getName());
    try (Statement stm = conn.createStatement();
        ResultSet rs = stm.executeQuery(sql)) {

      ResultSetMetaData columnMetaData = rs.getMetaData();
      int columnCount = columnMetaData.getColumnCount();
      for (int i = 1; i <= columnCount; i++) {
        ColumnMeta columnMeta = new ColumnMeta();
        columnMeta.setName(columnMetaData.getColumnName(i));

        String dataType = columnMetaData.getColumnTypeName(i);
        columnMeta.setType(dataType);

        String jdbcType = columnMetaData.getColumnClassName(i);
        columnMeta.setPropertyType(JdbcTypeMapping.getType(jdbcType));
        columnMeta.setAutoIncrement(columnMetaData.isAutoIncrement(i));

        // 注释
        columnMeta.setComment(columnRemarks.get(columnMeta.getName()));

        tableMeta.addColumn(columnMeta);
      }
    }
  }

  @Override
  public ResultSet getTablesResultSet(
      DatabaseMetaData dbMeta, Connection conn, String schema, String[] types) throws SQLException {
    return dbMeta.getTables(conn.getCatalog(), schema, null, types);
  }

  private Map<String, String> buildColumnRemarks(
      TableMeta tableMeta, DatabaseMetaData dbMeta, Connection conn) {
    Map<String, String> columnRemarks = new HashMap<>();
    try (ResultSet colRs = dbMeta.getColumns(conn.getCatalog(), null, tableMeta.getName(), null)) {
      while (colRs.next()) {
        columnRemarks.put(colRs.getString("COLUMN_NAME"), colRs.getString("REMARKS"));
      }
    } catch (Exception e) {
      System.err.println("无法获取字段的备注内容：" + e.getMessage());
    }
    return columnRemarks;
  }

  /**
   * 构建查询所有数据的 SQL 语句
   *
   * @param schema 模式
   * @param tableName 表名
   * @return 全量查询 SQL 语句
   */
  abstract String forBuildColumnsSql(String schema, String tableName);
}
